#include once <neg32.asm>
#include once <_mul32.asm>
;
__MULF16:    ;
lda z80_d                 ;- ld a,d            ; load sgn into a
sta z80_a
ldx z80_ap                ;- ex af,af'         ; saves it
sta z80_ap
txa
jsr __ABS32               ;- call __ABS32         ; convert to positive
lda z80_c                 ;- exx
ldx z80_cp
stx z80_c
sta z80_cp
lda z80_b
ldx z80_bp
stx z80_b
sta z80_bp
lda z80_e
ldx z80_ep
stx z80_e
sta z80_ep
lda z80_d
ldx z80_dp
stx z80_d
sta z80_dp
lda z80_l
ldx z80_lp
stx z80_l
sta z80_lp
lda z80_h
ldx z80_hp
stx z80_h
sta z80_hp
pla                        ;- pop hl ; Return address
sta z80_h
pla
sta z80_l
pla                        ;- pop de ; Low part
sta z80_d
pla
sta z80_e
tsx                        ;- ex (sp), hl ; CALLEE caller convention; Now HL = Hight part, (SP) = Return address
lda $0103,x
ldy z80_h
sta z80_h
tya
sta $0103,x
lda $0104,x
ldy z80_l
sta z80_l
tya
sta $104,x
lda z80_e                  ;- ex de,hl  ; D'E' = High part (B),  H'L' = Low part (B) (must be in DE)
ldx z80_l
stx z80_e
sta z80_l
lda z80_d
ldx z80_h
stx z80_d
sta z80_h
ldx z80_ap                 ;- ex af,af'
sta z80_ap
txa
eor z80_d                  ;- xor d               ; A register contains resulting sgn
ldx z80_ap                 ;- ex af,af'
sta z80_ap
txa
jsr __ABS32                ;- call __ABS32         ; convert to positive
jsr call __MUL32_64START   ;- call __MUL32_64START

; rounding (was not included in zx81)
__ROUND_FIX:               ; rounds a 64bit (32.32) fixed point number to 16.16
; result returned in dehl
; input in h'l'hlb'c'ac
asl z80_a                  ;- sla a               ; result bit 47 to carry
lda z80_c                  ;- exx
ldx z80_cp
stx z80_c
sta z80_cp
lda z80_b
ldx z80_bp
stx z80_b
sta z80_bp
lda z80_e
ldx z80_ep
stx z80_e
sta z80_ep
lda z80_d
ldx z80_dp
stx z80_d
sta z80_dp
lda z80_l
ldx z80_lp
stx z80_l
sta z80_lp
lda z80_h
ldx z80_hp
stx z80_h
sta z80_hp
lda #<0              ;- ld hl,0            ; ld does not change carry
sta z80_l
lda #>0
sta z80_h
                     ;- adc hl,bc           ; hl = hl + 0 + carry
lda z80_l            ;- push hl
pha
lda z80_h
pha
lda z80_c            ;- exx
ldx z80_cp
stx z80_c
sta z80_cp
lda z80_b
ldx z80_bp
stx z80_b
sta z80_bp
lda z80_e
ldx z80_ep
stx z80_e
sta z80_ep
lda z80_d
ldx z80_dp
stx z80_d
sta z80_dp
lda z80_l
ldx z80_lp
stx z80_l
sta z80_lp
lda z80_h
ldx z80_hp
stx z80_h
sta z80_hp
lda #<0              ;- ld bc,0
sta z80_c
lda #>0
sta z80_b
                     ;- adc hl,bc           ; hl = hl + 0 + carry
lda z80_e            ;- ex de,hl
ldx z80_l
stx z80_e
sta z80_l
lda z80_d
ldx z80_h
stx z80_d
sta z80_h
pla                  ;- pop hl              ; rounded result in de.hl
sta z80_h
pla
sta z80_l
ldx z80_ap           ;- ex af,af'         ; recovers result sign
sta z80_ap
txa
ora z80_a            ;- or a
jmi __NEG32          ;- jp m, __NEG32      ; if negative, negates it
rts                  ;- ret

